package com.example.test_bluetooth;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements Serializable{

	private Button activation;
	private Button bluetooth2;
	private Button decouverte;
	private Button quit;
	private Button server;
	private Button newp;
	private Button lirecs;
	private Button envoiecs;
	private Button client;
	private Button envoi1;
	private Button envoi2;
	private Button lire;
	private Button choix_serveur;
	private EditText scoreclient;
	private TextView receptionscore;
	private Button envoieatous;
	private Button liste_co;
	private Spinner spinnerclient;

	private ArrayList<ThreadSocketTransfert> ensemblethreadclient = new ArrayList<ThreadSocketTransfert>();
	private HashMap<ThreadSocketTransfert, String[]> listeclient = new HashMap<MainActivity.ThreadSocketTransfert, String[]>();

	private final UUID uuid = UUID.fromString("80a6f6d4-8c79-4eed-b391-7fefd6a259ec");

	private AcceptThread acceptThread;
	private ConnectThread connectThread;
	private ConnectedThread connectedThread;
	private StringBuilder st = new StringBuilder(1024);
	private ThreadSocketTransfert tst;

	private BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
	private ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();

	private static final int DISCOVERY_REQUEST = 0;
	private static final String TAG = "MyActivity";
	private Dialog dialog;
	private Set<BluetoothDevice> devices;

	private String adresse = bluetooth.getAddress();
	private BluetoothDevice device = bluetooth.getRemoteDevice(adresse);

	private String result = "";
	private List<String> lclient = new ArrayList<String>();
	
	private boolean estclient = false;
	private boolean estserveur = false;
	private ChoixServeur cs = new ChoixServeur();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		initBluetooth();

		activation = (Button) findViewById(R.id.button1);
		bluetooth2 = (Button) findViewById(R.id.bluetooth2);
		decouverte = (Button) findViewById(R.id.decouverte);
		quit =  (Button) findViewById(R.id.quit);
		server =  (Button) findViewById(R.id.server);
		lirecs = (Button) findViewById(R.id.lirecs);
		envoiecs = (Button) findViewById(R.id.envoiecs);
		newp = (Button) findViewById(R.id.newp);
		client = (Button) findViewById(R.id.client);
		envoi1 = (Button) findViewById(R.id.envoie1);
		envoi2 = (Button) findViewById(R.id.envoie2);
		lire = (Button) findViewById(R.id.lire);
		choix_serveur = (Button) findViewById(R.id.choix_serveur);
		scoreclient = (EditText) findViewById(R.id.scoreClient);
		receptionscore = (TextView) findViewById(R.id.receptionscore);
		envoieatous = (Button) findViewById(R.id.envoieatous);
		liste_co = (Button) findViewById(R.id.liste_co);
		spinnerclient = (Spinner) findViewById(R.id.spinnerClient);
		
		

		liste_co.setOnClickListener(new View.OnClickListener() {

			public void onClick(View v) {
				//Intent intent = new Intent(MainActivity.this, listeClient.class);
				//intent.putExtra("liste", listeclient);
				//startActivity(intent);
				for(Entry<ThreadSocketTransfert, String[]> entry : listeclient.entrySet()) {
					//TypeCle cle = entry.getKey();
					//  TypeValeur valeur = entry.getValue();
					Log.d(TAG, entry.getKey().toString() + entry.getValue()[0].toString() +" "+ entry.getValue()[1].toString() );
					lclient.add(entry.getValue()[0].toString());
				}
				spinnerclient.invalidate();
				ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_item, lclient);
			    //Le layout par défaut est android.R.layout.simple_spinner_dropdown_item
			    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			    spinnerclient.setAdapter(adapter);
				//setListAdapter(new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_spinner_item,lclient));
			}
			
		});

		envoieatous.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				envoieatous();
			}
		});


		choix_serveur.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {	
				Intent intent = new Intent(MainActivity.this, ChoixServeur.class);
				startActivity(intent);
			}
		});

		envoi1.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if(estclient){
					Toast.makeText(MainActivity.this, "Il y a déjà un serveur", Toast.LENGTH_SHORT).show();
					return;
				}
				connectedThread = new ConnectedThread();
				connectedThread.sendMessage(((ThreadSocketTransfert) ensemblethreadclient.get(0)).getTransfertSocket(), "test envoie message au client 1");

			}
		});

		envoi2.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if(estclient){
					Toast.makeText(MainActivity.this, "Il y a déjà un serveur", Toast.LENGTH_SHORT).show();
					return;
				}
				connectedThread = new ConnectedThread();
				connectedThread.sendMessage(((ThreadSocketTransfert) ensemblethreadclient.get(1)).getTransfertSocket(), "test envoie message au client2");

			}
		});

		lire.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if(estserveur){
					Toast.makeText(MainActivity.this, "Tu es le serveur et non un client, pourquoi veut tu te rabaisser a leur niveau?", Toast.LENGTH_SHORT).show();
					return;
				}
				connectedThread = new ConnectedThread();
				try {
					connectedThread.listenForMessages(connectThread.getSocketTransfert(), st);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});


		envoiecs.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				String score = scoreclient.getText().toString();

				if(estserveur){
					Toast.makeText(MainActivity.this, "Tu es le serveur et non un client, pourquoi veut tu te rabaisser a leur niveau?", Toast.LENGTH_SHORT).show();
					return;
				}
				connectedThread = new ConnectedThread();
				connectedThread.sendMessage(connectThread.getSocketTransfert(), score /*"envoie message client-serveur"*/);

			}
		});

		lirecs.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if(estclient){
					Toast.makeText(MainActivity.this, "Il y a déjà un serveur", Toast.LENGTH_SHORT).show();
					return;
				}
				connectedThread = new ConnectedThread();
				try {
					connectedThread.listenForMessages(((ThreadSocketTransfert) ensemblethreadclient.get(0)).getTransfertSocket(), st);
					receptionscore.setText(st);
					st.delete(0, st.length());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});


		activation.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				//initBluetooth();
				Intent intentBluetooth = new Intent();
				intentBluetooth.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
				startActivity(intentBluetooth); 
			}
		});

		bluetooth2.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				initBluetooth();
			}
		});

		decouverte.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				//	devices = bluetooth.getBondedDevices();
				//	for (BluetoothDevice blueDevice : devices) {
				//	Toast.makeText(MainActivity.this, "Device = " + blueDevice.getName(), Toast.LENGTH_SHORT).show();
				//}

				//startDiscovery();
				Toast.makeText(MainActivity.this, "je suis ici", Toast.LENGTH_SHORT).show();
				for(BluetoothDevice bt : ChoixServeur.getDeviceList())
					Toast.makeText(MainActivity.this, "Device " + bt.getName(), Toast.LENGTH_SHORT).show();
			}			
		});

		newp.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				bluetooth.startDiscovery();
				IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
				registerReceiver(bluetoothReceiver, filter);

			}			
		});


		quit.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Builder builder = new AlertDialog.Builder(MainActivity.this);
				builder.setTitle("Confirmation fermeture");				


				builder.setMessage("Voulez vous quitter ?");
				builder.setPositiveButton("oui", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						System.exit(0);
					}
				}
						);
				builder.setNegativeButton("non j'ai la flemme", null);
				builder.show();
			}
		});

		server.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if(estclient){
					Toast.makeText(MainActivity.this, "Il y a déjà un serveur", Toast.LENGTH_SHORT).show();
					return;
				}

				estserveur=true;
				Toast.makeText(MainActivity.this, "Bonjour monsieur le serveur", Toast.LENGTH_SHORT).show();
				acceptThread = new AcceptThread();
				Toast.makeText(MainActivity.this, "Nous t'avons créé ton thread", Toast.LENGTH_SHORT).show();
				//acceptThread.startServerSocket(bluetooth);
				acceptThread.start();

			}
		});

		client.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				bluetooth.cancelDiscovery();
				if(estserveur){
					Toast.makeText(MainActivity.this, "Tu es le serveur et non un client, pourquoi veut tu te rabaisser a leur niveau?", Toast.LENGTH_SHORT).show();
					return;
				}
				estclient = true;
				String serveurchoisi = ChoixServeur.getServeurChoisi();
				ArrayList<BluetoothDevice> serv = ChoixServeur.getDeviceList();//bluetooth.getBondedDevices();
				if(serv.isEmpty())
					Toast.makeText(MainActivity.this, "vide", Toast.LENGTH_SHORT).show();
				//Toast.makeText(MainActivity.this, "Vous vous connectez au serveur "+serveurchoisi, Toast.LENGTH_SHORT).show();
				if(serv.size() > 0){
					Toast.makeText(MainActivity.this, "Vous vous connectez au serveur "+serveurchoisi, Toast.LENGTH_SHORT).show();
					for(BluetoothDevice device : serv){
						if(device.getName().compareTo(/*intent.getStringExtra(EXTRA_SERVEUR)*/serveurchoisi) == 0){
							Toast.makeText(MainActivity.this, device.getName(), Toast.LENGTH_SHORT).show();
							connectThread = new ConnectThread();
							//Toast.makeText(MainActivity.this, "je suis ici", Toast.LENGTH_SHORT).show();
							connectThread.connectToServerSocket(device, uuid);
						}
					}
				}

			}

		});


	}


	private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
		public void onReceive(Context context, Intent intent) {
			Log.d(TAG, "dans broadcatsreceveir bluetootreceiver");
			String action = intent.getAction();
			if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				Toast.makeText(MainActivity.this, "New Device = " + device.getName(), Toast.LENGTH_SHORT).show();
			}
		}
	};

	@Override
	protected void onDestroy() {
		super.onDestroy();
		bluetooth.cancelDiscovery();
		unregisterReceiver(bluetoothReceiver);
	}

	public void initBluetooth() {
		if(!bluetooth.isEnabled()) {
			//Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			//startActivityForResult(intent, ENABLE_BLUETOOTH);
			startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE), DISCOVERY_REQUEST);

		}
	}

	public void prendrephoto()
	{
		// create Intent to take a picture and return control to the calling application
		Intent imageIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
		imagesFolder.mkdirs(); // <----
		File image = new File(imagesFolder, "image_001.jpg");
		Uri uriSavedImage = Uri.fromFile(image);
		imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
		startActivityForResult(imageIntent,0);
	}

	private void startDiscovery() {
		registerReceiver(discoveryResult, new IntentFilter(BluetoothDevice.ACTION_FOUND));

		if(bluetooth.isEnabled() && !bluetooth.isDiscovering())
			deviceList.clear();
		bluetooth.startDiscovery();
	}
	BroadcastReceiver discoveryResult = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			Log.d(TAG, "dans broadcatsreceveir discoveryresult");
			String remoteDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
			BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
			deviceList.add(remoteDevice);
			Log.d(TAG, "Decouverte " + remoteDeviceName);
		}


	};


	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		if(requestCode == DISCOVERY_REQUEST) {
			if(resultCode == RESULT_CANCELED) {
				Log.d(TAG, "visibilit� annul�e par l'utilisateur");
			}
		}
	}

	protected Dialog onCreateDialog() {
		// Cr�ation d'un boite de dialogue 

		AlertDialog.Builder builder = new AlertDialog.Builder(this);

		builder.setMessage("Voulez-vous supprimer le sms ?");
		builder.setCancelable(false);
		builder.setTitle("Confirmation");

		builder.setPositiveButton("OUI",
				new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {

				System.exit(0);
			}
		});

		builder.setNegativeButton("NON",
				new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
			}
		});

		dialog = builder.create();
		return dialog;
	}

	public BluetoothDevice getDevice() {
		return device;
	}


	public ArrayList<BluetoothDevice> getDeviceList() {
		return deviceList;
	}

	public void setDeviceList(ArrayList<BluetoothDevice> deviceList) {
		this.deviceList = deviceList;
	}

	public void setDevice(BluetoothDevice device) {
		this.device = device;
	}

	public void envoieatous()
	{
		for(ThreadSocketTransfert ts : ensemblethreadclient)
		{
			connectedThread = new ConnectedThread();
			connectedThread.sendMessage(ts.getTransfertSocket(), "test envoie message a tous les clients");
		}
	}


	public class AcceptThread extends Thread {

		private final BluetoothServerSocket blueServerSocket;
		private String NAME = "TournamentManager";
		private String nombluetooth;
		private String addmac;


		public AcceptThread() {

			BluetoothServerSocket tmp = null;
			try {   
				tmp = bluetooth.listenUsingRfcommWithServiceRecord(NAME, uuid);
			} catch (IOException e) { }
			blueServerSocket = tmp;
		}

		public void run() {
			BluetoothSocket blueSocket = null;
			while (true) {
				try {

					runOnUiThread(new Runnable() {
						public void run() {

							Toast.makeText(MainActivity.this,"avant accept dans serveur",Toast.LENGTH_LONG).show();
						}
					});

					blueSocket = blueServerSocket.accept();
					runOnUiThread(new Runnable() {
						public void run() {

							Toast.makeText(MainActivity.this,"aapres accept dans serveur",Toast.LENGTH_LONG).show();
						}
					});

				} catch (IOException e) {
					break;
				}
				if (blueSocket != null) {
					tst = new ThreadSocketTransfert(blueSocket);
					ensemblethreadclient.add(tst);

					connectedThread = new ConnectedThread();

					try {
						connectedThread.listenForMessages(blueSocket, st);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					nombluetooth = st.substring(st.indexOf("<name>")+6, st.indexOf("</name>"));
					addmac = st.substring(st.indexOf("<mac>")+5, st.indexOf("</mac>"));
					Log.d(TAG, "name : " + nombluetooth + ", mac : "+ addmac);
					listeclient.put(tst, new String[] {nombluetooth,addmac});
					st.delete(0, st.length());
					tst.start();
					/*try {
						blueServerSocket.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
					break;*/
				}
			}
		}


		public void cancel() {
			try {
				blueServerSocket.close();
			} catch (IOException e) { }
		}
	}



	private class ThreadSocketTransfert extends Thread{

		private BluetoothSocket transfertSocket;
		private ConnectedThread connectedThread;

		public ThreadSocketTransfert(BluetoothSocket btSocket)
		{
			transfertSocket = btSocket;
			connectedThread = new ConnectedThread();
		}

		public BluetoothSocket getTransfertSocket()
		{
			return transfertSocket;
		}

		public void run() {
			runOnUiThread(new Runnable() {
				public void run() {

					Toast.makeText(MainActivity.this,"avant sendMessage",Toast.LENGTH_LONG).show();
				}
			});

			//connectedThread.sendMessage(transfertSocket, "coucou c'est moi toto");

			runOnUiThread(new Runnable() {
				public void run() {

					Toast.makeText(MainActivity.this,"après sendMessage",Toast.LENGTH_LONG).show();
				}
			});
		}
	}



	private class ConnectThread extends Thread {
		private BluetoothSocket transfertSocket;

		private void connectToServerSocket(BluetoothDevice device, UUID uuid)
		{
			try {
				BluetoothSocket clientSocket = device.createRfcommSocketToServiceRecord(uuid);
				Log.v(TAG, "create rf uuid :" + uuid.toString());
				clientSocket.connect();

				Log.v(TAG, "clientSocket connecté :" );
				//listenForMessages(clientSocket,st);
				transfertSocket = clientSocket;
				connectedThread = new ConnectedThread();
				connectedThread.sendMessage(connectThread.getSocketTransfert(), "<msg><name>" + bluetooth.getName() + "</name><mac>"+ bluetooth.getAddress()+"</mac></msg>");
				//Log.d(TAG, bluetooth.getName() + bluetooth.getAddress());
			} catch (IOException e) {
			}
		}

		public BluetoothSocket getSocketTransfert()
		{
			return transfertSocket;
		}

	}





	public class ConnectedThread extends Thread{

		private synchronized void sendMessage(BluetoothSocket socket,String message){
			OutputStream ops;
			try{
				ops= socket.getOutputStream();
				byte[] byteArray =(message+" ").getBytes();
				byteArray [byteArray.length -1]=0;
				ops.write(byteArray);
			}
			catch(IOException e){
				Log.d("BLUETOOTH", "BLUETOOTH client I/O EXCEPTION", e);
			}
		}

		private boolean listening = false;

		private synchronized void listenForMessages(BluetoothSocket socket,StringBuilder incomming) throws IOException{
			listening = true;
			int buffersize = 1024;
			byte[]buffer = new byte[buffersize];
			try{
				InputStream ips = socket.getInputStream();
				int byteRead = -1;
				while (listening){
					byteRead = ips.read(buffer);
					Log.d("BLUETOOTH", "listenfromMessage");
					System.out.println("dans listen");
					if(byteRead != -1){
						//String result = "";
						while((byteRead == buffersize)&& buffer[buffersize-1]!=0){
							result = result + new String(buffer,0,byteRead -1);
							byteRead = ips.read(buffer);

						}
						result = result + new String(buffer,0,byteRead -1);
						incomming.append(result);
						System.out.println("result : " + result);

						runOnUiThread(new Runnable() {
							public void run() {

								Toast.makeText(MainActivity.this,"J'ai reçu le message : "+ result ,Toast.LENGTH_LONG).show();
							}
						});


						listening = false;
						result = "";
					}
				}

			}
			catch(IOException e){
				Log.d(TAG, "Echec de la reception du message", e);
			}
			finally{
				//socket.close();
			}
		}

	}






}
